package com.wyzz.hr.bo.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;

import com.wyzz.hr.base.BaseAction;
import com.wyzz.hr.bo.IDepartmentBO;
import com.wyzz.hr.bo.IEmployeeBo;
import com.wyzz.hr.bo.ILeavebalanceBO;
import com.wyzz.hr.bo.ILeaverequestBO;
import com.wyzz.hr.dao.IEmployeeDAO;
import com.wyzz.hr.dao.ILeavebalanceDAO;
import com.wyzz.hr.pojo.Department;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Leavebalance;
import com.wyzz.hr.pojo.Leaverequest;
import com.wyzz.hr.pojo.Leavetype;
import com.wyzz.hr.pojo.Location;
import com.wyzz.hr.pojo.Overtimerequest;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.support.BigDecimalUtils;
import com.wyzz.hr.util.BaseCrit;
import com.wyzz.hr.util.DateUtil;
import com.wyzz.hr.util.InterpreterException;
import com.wyzz.hr.util.InterpreterExecuteContext;
import com.wyzz.hr.util.MyTools;
import com.wyzz.hr.util.Pager;
import com.wyzz.hr.vo.LeaveBalanceSearchBean;
import com.wyzz.hr.vo.LeaveReportBean;

public class LeavebalanceBOImpl implements ILeavebalanceBO {

	public LeavebalanceBOImpl() {
	}

	public Leavebalance getLeavebalance(Employee currentEmp, String year) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_EMP_NO,
				currentEmp));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, year));
		List result = lb_DAO.findByCriteria(detachedCriteria);
		if (result.size() == 0)
			return null;
		List otList = getOtForwardOfYear(Integer.parseInt(year) + 1);
		BigDecimal lbTiaoxiuForward = null;
		Leavebalance lb;
		for (Iterator i$ = result.iterator(); i$.hasNext(); lb
				.setLbTiaoxiuYearCanUse(lbTiaoxiuForward.add(lb
						.getLbTiaoxiuCurrent()))) {
			lb = (Leavebalance) i$.next();
			lbTiaoxiuForward = lb.getLbTiaoxiuForward() == null ? new BigDecimal(
					0)
					: lb.getLbTiaoxiuForward();
			lb.setLbTiaoxiuCurrent(getCurrEmpTiaoxiuOt(lb.getLbEmpNo().getId(),
					otList));
		}

		return (Leavebalance) result.get(0);
	}

	public Leavebalance getLeavebalance(Employee currentEmp, String year,
			Leavetype lrLtNo) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_EMP_NO,
				currentEmp));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, year));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_LEAVE_TYPE,
				lrLtNo.getLtSpecialCat()));
		List result = lb_DAO.findByCriteria(detachedCriteria);
		if (result.size() == 0)
			return null;
		else
			return (Leavebalance) result.get(0);
	}

	public List getHistoryLeavebalanceList(LeaveBalanceSearchBean lb_Bean,
			Pager page) {
		List result = null;
		if (lb_Bean.getDepNo() != null
				&& lb_Bean.getDepNo().trim().length() > 0
				&& dp_BO.loadDepartmentByNo(lb_Bean.getDepNo(), new String[0]) == null)
			return null;
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.setFetchMode(Leavebalance.PROP_LB_EMP_NO,
				FetchMode.JOIN);
		detachedCriteria.setFetchMode((new StringBuilder()).append(
				Leavebalance.PROP_LB_EMP_NO).append(".").append(
				Employee.PROP_EMP_DEPT_NO).toString(), FetchMode.JOIN);
		detachedCriteria.createAlias(Leavebalance.PROP_LB_EMP_NO,
				Leavebalance.PROP_LB_EMP_NO);
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, String
				.valueOf(lb_Bean.getYear())));
		if (lb_Bean.getEmp() != null && lb_Bean.getEmp().trim().length() > 0)
			detachedCriteria.add(Restrictions.or(Restrictions.ilike(
					(new StringBuilder()).append(Leavebalance.PROP_LB_EMP_NO)
							.append(".").append(Employee.PROP_EMP_DISTINCT_NO)
							.toString(), (new StringBuilder()).append("%")
							.append(lb_Bean.getEmp()).append("%").toString()),
					Restrictions.ilike((new StringBuilder()).append(
							Leavebalance.PROP_LB_EMP_NO).append(".").append(
							Employee.PROP_EMP_NAME).toString(),
							(new StringBuilder()).append("%").append(
									lb_Bean.getEmp()).append("%").toString())));
		if (lb_Bean.getDepNo() != null
				&& lb_Bean.getDepNo().trim().length() > 0)
			detachedCriteria.add(Restrictions.eq((new StringBuilder()).append(
					Leavebalance.PROP_LB_EMP_NO).append(".").append(
					Employee.PROP_EMP_DEPT_NO).toString(), new Department(
					lb_Bean.getDepNo())));
		page.splitPage(detachedCriteria);
		result = lb_DAO.findByCriteria(detachedCriteria, page.getPageSize(),
				page.getCurrentPage());
		List otList = getOtForwardOfYear(lb_Bean.getYear() + 1);
		BigDecimal lbTiaoxiuForward = null;
		Leavebalance lb;
		for (Iterator i$ = result.iterator(); i$.hasNext(); lb
				.setLbTiaoxiuYearCanUse(lbTiaoxiuForward.add(lb
						.getLbTiaoxiuCurrent()))) {
			lb = (Leavebalance) i$.next();
			lbTiaoxiuForward = lb.getLbTiaoxiuForward() == null ? new BigDecimal(
					0)
					: lb.getLbTiaoxiuForward();
			lb.setLbTiaoxiuCurrent(getCurrEmpTiaoxiuOt(lb.getLbEmpNo().getId(),
					otList));
		}

		return result;
	}

	public List getLeavebalanceList(LeaveBalanceSearchBean lb_Bean, Pager page,
			List otList) {
		List result = null;
		if (lb_Bean.getDepNo() != null
				&& lb_Bean.getDepNo().trim().length() > 0
				&& dp_BO.loadDepartmentByNo(lb_Bean.getDepNo(), new String[0]) == null)
			return null;
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Employee.class);
		detachedCriteria
				.setFetchMode(Employee.PROP_EMP_DEPT_NO, FetchMode.JOIN);
		if (lb_Bean.getYear() >= Calendar.getInstance().get(1))
			detachedCriteria.add(Restrictions.eq(Employee.PROP_EMP_STATUS,
					Integer.valueOf(1)));
		if (lb_Bean.getEmp() != null && lb_Bean.getEmp().trim().length() > 0)
			detachedCriteria.add(Restrictions.or(Restrictions.ilike(
					Employee.PROP_EMP_DISTINCT_NO, (new StringBuilder())
							.append("%").append(lb_Bean.getEmp()).append("%")
							.toString()), Restrictions.ilike(
					Employee.PROP_EMP_NAME, (new StringBuilder()).append("%")
							.append(lb_Bean.getEmp()).append("%").toString())));
		if (lb_Bean.getDepNo() != null
				&& lb_Bean.getDepNo().trim().length() > 0)
			detachedCriteria.add(Restrictions.eq(Employee.PROP_EMP_DEPT_NO,
					new Department(lb_Bean.getDepNo())));
		detachedCriteria.addOrder(Order.asc(Employee.PROP_ID));
		page.splitPage(detachedCriteria);
		result = e_DAO.findByCriteria(detachedCriteria, page.getPageSize(),
				page.getCurrentPage());
		DetachedCriteria detachedCriteria_lb = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.setFetchMode(Leavebalance.PROP_LB_EMP_NO,
				FetchMode.JOIN);
		if (lb_Bean.getYear() > 0)
			detachedCriteria_lb.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR,
					(new StringBuilder()).append("").append(lb_Bean.getYear())
							.toString()));
		detachedCriteria_lb.addOrder(Order.asc(Leavebalance.PROP_LB_EMP_NO));
		List lb_temp = lb_DAO.findByCriteria(detachedCriteria_lb);
		int j = 0;
		for (int i = 0; i < result.size(); i++) {
			if (j >= lb_temp.size()) {
				((Employee) result.get(i)).setEmpleaveblances(null);
				j++;
				continue;
			}
			if (((Employee) result.get(i)).getId().compareTo(
					((Leavebalance) lb_temp.get(j)).getLbEmpNo().getId()) > 0) {
				j++;
				i--;
				continue;
			}
			if (((Employee) result.get(i)).getId().compareTo(
					((Leavebalance) lb_temp.get(j)).getLbEmpNo().getId()) < 0) {
				((Employee) result.get(i)).setEmpleaveblances(null);
				continue;
			}
			Set lbSet = new HashSet();
			Leavebalance lb = (Leavebalance) lb_temp.get(j);
			lb.setLbTiaoxiuCurrent(getCurrEmpTiaoxiuOt(lb.getLbEmpNo().getId(),
					otList));
			if (lb.getLbTiaoxiuForward() == null)
				lb.setLbTiaoxiuForward(new BigDecimal(0));
			lb.setLbTiaoxiuYearCanUse(lb.getLbTiaoxiuCurrent().add(
					lb.getLbTiaoxiuForward()));
			lbSet.add(lb);
			((Employee) result.get(i)).setEmpleaveblances(lbSet);
			j++;
		}

		return result;
	}

	public List getEmpWithLB(Leavebalance leaveBalance, Pager page) {
		DetachedCriteria dc = createDCEmp_LB(leaveBalance);
		List lbList;
		if (page != null) {
			BaseAction.addOrders(dc, page, new String[] { (new StringBuilder())
					.append("emp.").append(Employee.PROP_EMP_DISTINCT_NO)
					.append("-up").toString() });
			page.splitPage(dc);
			lbList = e_DAO.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		} else {
			dc.createAlias((new StringBuilder()).append("emp.").append(
					Employee.PROP_EMP_DEPT_NO).toString(), "empDeptNo", 1);
			dc.createAlias((new StringBuilder()).append("emp.").append(
					Employee.PROP_EMP_PB_NO).toString(), "empPbNo", 1);
			lbList = e_DAO.findByCriteria(dc);
		}
		if (lbList.size() == 0)
			return null;
		List resultEmpList = new ArrayList(lbList.size());
		Employee emp;
		for (Iterator i$ = lbList.iterator(); i$.hasNext(); resultEmpList
				.add(emp)) {
			Leavebalance bal = (Leavebalance) i$.next();
			emp = bal.getLbEmpNo();
			emp.setLeaveBalance(bal);
		}

		return resultEmpList;
	}

	public List getEmpWithoutLB(Leavebalance leaveBalance, Pager page) {
		DetachedCriteria dc = createDCEmp(leaveBalance);
		List empList = e_DAO.findByCriteria(dc);
		dc = createDCEmp_LB(leaveBalance);
		List lbList = e_DAO.findByCriteria(dc);
		if (empList.size() == 0)
			return empList;
		Map lbMap = new HashMap();
		if (lbList.size() > 0) {
			String empId;
			for (Iterator i$ = lbList.iterator(); i$.hasNext(); lbMap.put(
					empId, empId)) {
				Leavebalance lb = (Leavebalance) i$.next();
				empId = lb.getLbEmpNo().getId();
			}

		}
		Employee emp = null;
		int count = 0;
		for (Iterator iter = empList.iterator(); iter.hasNext();) {
			emp = (Employee) iter.next();
			if (lbMap.get(emp.getId()) != null)
				iter.remove();
			else
				count++;
		}

		if (page == null)
			return empList;
		if (count == 0)
			return empList;
		String empIds[] = new String[count];
		count = 0;
		for (Iterator i$ = empList.iterator(); i$.hasNext();) {
			Employee empTemp = (Employee) i$.next();
			empIds[count] = empTemp.getId();
			count++;
		}

		dc = createDCEmp(leaveBalance);
		dc.addOrder(Order.asc(Employee.PROP_EMP_DISTINCT_NO));
		dc.add(Restrictions.in(Employee.PROP_ID, empIds));
		page.splitPage(dc);
		empList = e_DAO.findByCriteria(dc, page.getPageSize(), page
				.getCurrentPage());
		return empList;
	}

	private DetachedCriteria createDCEmp_LB(Leavebalance leaveBalance) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		dc.createAlias(Leavebalance.PROP_LB_EMP_NO, "emp", 1);
		dc.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, leaveBalance
				.getLbYear()));
		dc.add(Restrictions.eq(Leavebalance.PROP_LB_LEAVE_TYPE, leaveBalance
				.getLbLeaveType()));
		java.util.Date startDate = DateUtil.getYearFirstDay(Integer
				.parseInt(leaveBalance.getLbYear()));
		java.util.Date endDate = DateUtil.getYearEndDay(Integer
				.parseInt(leaveBalance.getLbYear()));
		dc.add(Restrictions.le((new StringBuilder()).append("emp.").append(
				Employee.PROP_EMP_JOIN_DATE).toString(), endDate));
		dc.add(Restrictions.or(Restrictions.eq((new StringBuilder()).append(
				"emp.").append(Employee.PROP_EMP_STATUS).toString(), Integer
				.valueOf(1)), Restrictions.and(Restrictions.eq(
				(new StringBuilder()).append("emp.").append(
						Employee.PROP_EMP_STATUS).toString(), Integer
						.valueOf(0)), Restrictions.ge((new StringBuilder())
				.append("emp.").append(Employee.PROP_EMP_TERMINATE_DATE)
				.toString(), startDate))));
		Employee emp = leaveBalance.getLbEmpNo();
		if (emp != null) {
			BaseCrit.addEmpDC(dc, "emp", emp.getEmpNoName());
			BaseCrit.addDeptDC(dc, (new StringBuilder()).append("emp.").append(
					Employee.PROP_EMP_DEPT_NO).toString(),
					(new StringBuilder()).append("emp.").append(
							Employee.PROP_EMP_PB_NO).toString(), null, emp
							.getEmpDeptNo());
			BaseCrit.addDC(dc, (new StringBuilder()).append("emp.").append(
					Employee.PROP_EMP_LOCATION_NO).toString(),
					Location.PROP_ID, new Object[] { emp.getEmpLocationNo() });
		}
		if (leaveBalance.getLbStatus().intValue() == 1
				|| leaveBalance.getLbStatus().intValue() == 2
				|| leaveBalance.getLbStatus().intValue() == 9)
			dc.add(Restrictions.eq(Leavebalance.PROP_LB_STATUS, leaveBalance
					.getLbStatus()));
		return dc;
	}

	private DetachedCriteria createDCEmp(Leavebalance leaveBalance) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Employee.class);
		java.util.Date startDate = DateUtil.getYearFirstDay(Integer
				.parseInt(leaveBalance.getLbYear()));
		java.util.Date endDate = DateUtil.getYearEndDay(Integer
				.parseInt(leaveBalance.getLbYear()));
		dc.add(Restrictions.le(Employee.PROP_EMP_JOIN_DATE, endDate));
		dc.add(Restrictions.or(Restrictions.eq(Employee.PROP_EMP_STATUS,
				Integer.valueOf(1)), Restrictions.and(Restrictions.eq(
				Employee.PROP_EMP_STATUS, Integer.valueOf(0)), Restrictions.ge(
				Employee.PROP_EMP_TERMINATE_DATE, startDate))));
		Employee emp = leaveBalance.getLbEmpNo();
		if (emp != null) {
			BaseCrit.addEmpDC(dc, null, emp.getEmpNoName());
			BaseCrit.addDeptDC(dc, Employee.PROP_EMP_DEPT_NO,
					Employee.PROP_EMP_PB_NO, null, emp.getEmpDeptNo());
			BaseCrit.addDC(dc, Employee.PROP_EMP_LOCATION_NO, Location.PROP_ID,
					new Object[] { emp.getEmpLocationNo() });
		}
		return dc;
	}

	public List delLeavebalanceByYearAndEmp(Leavebalance lb) {
		List result = null;
		Leavebalance old_lb = null;
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_EMP_NO, lb
				.getLbEmpNo()));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, lb
				.getLbYear()));
		List tempList = lb_DAO.findByCriteria(detachedCriteria);
		if (tempList.size() > 0)
			old_lb = (Leavebalance) tempList.get(0);
		try {
			if (old_lb != null)
				lb_DAO.deleteObject(old_lb);
		} catch (Exception e) {
			result = new ArrayList();
			result.add(e.getMessage());
			return result;
		}
		return null;
	}

	public List exeLeaveBalanceInit(String empIds[], Integer ltSpecialCat[],
			String year) {
		if ((empIds == null) || (empIds.length == 0) || (ltSpecialCat == null)
				|| (ltSpecialCat.length == 0)) {
			return new ArrayList(0);
		}
		Map<Integer, Leavetype> typeMap = getLeaveTypeSpecial(ltSpecialCat);
		BigDecimal hourPerDay = new BigDecimal(8);
		int currentYear = Integer.valueOf(year).intValue();
		int lastYear = currentYear - 1;
		Map lbLastYearMap = getLeaveBalanceMap(empIds, lastYear);
		Map annualLastYearMap = getLeaveRequestMap(empIds, lastYear,
				(Leavetype) typeMap.get(Integer.valueOf(1)));
		Map txLastYearMap = getLeaveRequestMap(empIds, lastYear,
				(Leavetype) typeMap.get(Integer.valueOf(10)));
		Map txOTLastYearMap = getOTTiaoXiuMap(empIds, lastYear);
		List errors = new ArrayList();
		List leaveBalanceList = new ArrayList();
		IEmployeeBo empBo = (IEmployeeBo) SpringBeanFactory.getBean("empBo");
		List<Employee> emps = empBo.searchEmpArray(empIds);
		String yearMonth = year + "01";
		InterpreterExecuteContext context = new InterpreterExecuteContext(
				yearMonth);
		Leavetype leavetype;
		for (Integer specialCat : ltSpecialCat) {
			leavetype = (Leavetype) typeMap.get(specialCat);
			if (leavetype == null) {
				continue;
			}
			for (Employee emp : emps) {
				try {
					Leavebalance leavebalance = context.execute(leavetype, emp);
					leavebalance.setLbEmpNo(emp);
					leavebalance.setLbLeaveType(specialCat);
					leavebalance.setLbYear(year);
					leavebalance.setLbStatus(Integer.valueOf(1));
					if ((DateUtil.getYear(emp.getEmpJoinDate()) == currentYear)
							&& (leavetype.getLtReleaseMethod() != null)) {
						leavebalance
								.setLbReleaseStartDate(emp.getEmpJoinDate());
					}
					if (leavetype.getLtSpecialCat().intValue() == 1) {
						List balanceList = (List) lbLastYearMap
								.get(emp.getId());
						if (balanceList != null) {
							List lrList = (List) annualLastYearMap.get(emp
									.getId());
							Leavebalance lb = getBalanceFromList(balanceList,
									Integer.valueOf(1));
							BigDecimal balance = getLastYearBalance(lrList,
									leavetype, lb);
							BigDecimal release = getReleaseHours(lb, hourPerDay
									.doubleValue());
							BigDecimal totalLr = sumLRTotalHours(lrList);
							leavebalance.setLbBalForwardHour(balance.add(
									release).subtract(totalLr));
							leavebalance.setLbBalForwardDay(leavebalance
									.getLbBalForwardHour().divide(hourPerDay));
						}
						leaveBalanceList.add(leavebalance);
					}
					if (leavetype.getLtSpecialCat().intValue() == 10) {
						List balanceList = (List) lbLastYearMap
								.get(emp.getId());
						if (balanceList != null) {
							List lrList = (List) txLastYearMap.get(emp.getId());
							Leavebalance lb = getBalanceFromList(balanceList,
									Integer.valueOf(10));
							BigDecimal balance = getLastYearBalance(lrList,
									leavetype, lb);
							BigDecimal release = (BigDecimal) txOTLastYearMap
									.get(emp.getId());
							BigDecimal totalLr = sumLRTotalHours(lrList);
							leavebalance.setLbBalForwardHour(balance
									.subtract(totalLr));
							leavebalance.setLbBalForwardDay(leavebalance
									.getLbBalForwardHour().divide(hourPerDay));
							if (release != null) {
								leavebalance.setLbBalForwardHour(leavebalance
										.getLbBalForwardHour().add(release));
								leavebalance.setLbBalForwardDay(leavebalance
										.getLbBalForwardHour().divide(
												hourPerDay));
							}
						}
						leaveBalanceList.add(leavebalance);
					}
					if (leavetype.getLtSpecialCat().intValue() == 5)
						leaveBalanceList.add(leavebalance);
				} catch (InterpreterException e) {
					errors.add(e.getMessage());
				}
			}
		}
		if (!errors.isEmpty()) {
			return errors;
		}
		String hql = "delete from Leavebalance where lbLeaveType in"
				+ buildInCondition(ltSpecialCat) + " and lbEmpNo.id in"
				+ buildInCondition(empIds) + " and lbYear='" + year + "'";
		this.lb_DAO.exeHql(hql);
		this.lb_DAO.saveOrupdate(leaveBalanceList);
		return new ArrayList(0);
	}

	private BigDecimal sumLRTotalHours(List list) {
		BigDecimal result = new BigDecimal(0);
		if (list == null)
			return result;
		for (Iterator i$ = list.iterator(); i$.hasNext();) {
			Leaverequest leave = (Leaverequest) i$.next();
			result = result.add(leave.getLrTotalHours());
		}

		return result;
	}

	private Leavebalance getBalanceFromList(List list, Integer leaveType) {
		for (Iterator i$ = list.iterator(); i$.hasNext();) {
			Leavebalance lb = (Leavebalance) i$.next();
			if (lb.getLbLeaveType().equals(leaveType))
				return lb;
		}

		return null;
	}

	private Map getLeaveRequestMap(String empIds[], int year,
			Leavetype leaveType) {
		if (leaveType == null)
			return new HashMap(0);
		java.util.Date startDate = DateUtil.getYearFirstDay(year);
		java.util.Date endDate = DateUtil.getNextYearFirstDay(year);
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		dc.add(Restrictions.in((new StringBuilder()).append(
				Leaverequest.PROP_LR_EMP_NO).append(".id").toString(), empIds));
		dc.add(Restrictions.or(Restrictions.and(Restrictions.ge(
				Leaverequest.PROP_LR_START_DATE, startDate), Restrictions.lt(
				Leaverequest.PROP_LR_START_DATE, endDate)), Restrictions.and(
				Restrictions.le(Leaverequest.PROP_LR_END_DATE, endDate),
				Restrictions.gt(Leaverequest.PROP_LR_END_DATE, startDate))));
		dc.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO, leaveType));
		dc.addOrder(Order.asc(Leaverequest.PROP_LR_EMP_NO));
		List lrList = lb_DAO.findByCriteria(dc);
		if (lrList.size() == 0)
			return new HashMap(0);
		Map resultMap = new HashMap();
		String emp = ((Leaverequest) lrList.get(0)).getLrEmpNo().getId();
		List resultList = new ArrayList();
		resultList.add(lrList.get(0));
		for (int i = 1; i < lrList.size(); i++)
			if (emp.equals(((Leaverequest) lrList.get(i)).getLrEmpNo().getId())) {
				resultList.add(lrList.get(i));
			} else {
				resultMap.put(emp, resultList);
				emp = ((Leaverequest) lrList.get(i)).getLrEmpNo().getId();
				resultList.clear();
				resultList.add(lrList.get(i));
			}

		resultMap.put(emp, resultList);
		return resultMap;
	}

	private BigDecimal getLastYearBalance(List annualLRList, Leavetype lt,
			Leavebalance lb) {
		if (annualLRList == null || lb == null)
			return new BigDecimal(0);
		LrDataCheckImpl check = (LrDataCheckImpl) SpringBeanFactory
				.getBean("lrDataCheck");
		double hourPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		Double balFwdHours = check.getBalFwdHours(lb, hourPerDay);
		Double wastedHours;
		if (lb.getLbBalEndDate() == null) {
			wastedHours = new Double(0.0D);
		} else {
			double allHoursArr[] = check.getLeaveHoursBeforAfter(annualLRList,
					lb.getLbBalEndDate());
			wastedHours = Double.valueOf(allHoursArr[0] >= balFwdHours
					.doubleValue() ? (new Double(0.0D)).doubleValue()
					: balFwdHours.doubleValue() - allHoursArr[0]);
		}
		return new BigDecimal(balFwdHours.doubleValue()
				- wastedHours.doubleValue());
	}

	private BigDecimal getReleaseHours(Leavebalance lb, double hourPerDay) {
		if (lb == null) {
			return new BigDecimal(0);
		} else {
			LrDataCheckImpl check = (LrDataCheckImpl) SpringBeanFactory
					.getBean("lrDataCheck");
			return new BigDecimal(check.getCurrYearHours(lb, hourPerDay)
					.doubleValue());
		}
	}

	private Map getLeaveBalanceMap(String empIds[], int year) {
		Integer leaveTypes[] = { Integer.valueOf(1), Integer.valueOf(10) };
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		dc
				.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, String
						.valueOf(year)));
		dc.add(Restrictions.in((new StringBuilder()).append(
				Leavebalance.PROP_LB_EMP_NO).append(".id").toString(), empIds));
		dc.add(Restrictions.in(Leavebalance.PROP_LB_LEAVE_TYPE, leaveTypes));
		dc.addOrder(Order.asc(Leavebalance.PROP_LB_EMP_NO));
		List lbList = lb_DAO.findByCriteria(dc);
		if (lbList.size() == 0)
			return new HashMap(0);
		Map resultMap = new HashMap();
		String emp = ((Leavebalance) lbList.get(0)).getLbEmpNo().getId();
		List resultList = new ArrayList();
		resultList.add(lbList.get(0));
		for (int i = 1; i < lbList.size(); i++)
			if (emp.equals(((Leavebalance) lbList.get(i)).getLbEmpNo().getId())) {
				resultList.add(lbList.get(i));
			} else {
				resultMap.put(emp, resultList);
				emp = ((Leavebalance) lbList.get(i)).getLbEmpNo().getId();
				resultList.clear();
				resultList.add(lbList.get(i));
			}

		resultMap.put(emp, resultList);
		return resultMap;
	}

	private Map getOTTiaoXiuMap(String empIds[], int year) {
		Integer otStatus[] = { Integer.valueOf(15), Integer.valueOf(16) };
		java.util.Date startDate = DateUtil.getYearFirstDay(year);
		java.util.Date endDate = DateUtil.getNextYearFirstDay(year);
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Overtimerequest.class);
		dc.add(Restrictions.in((new StringBuilder()).append(
				Overtimerequest.PROP_OR_EMP_NO).append(".id").toString(),
				empIds));
		dc.add(Restrictions.gt(Overtimerequest.PROP_OR_TIAOXIU_HOURS,
				new BigDecimal(0)));
		dc.add(Restrictions.ge(Overtimerequest.PROP_OR_START_DATE, startDate));
		dc.add(Restrictions.le(Overtimerequest.PROP_OR_END_DATE, endDate));
		dc.add(Restrictions.in(Overtimerequest.PROP_OR_STATUS, otStatus));
		List otList = lb_DAO.findByCriteria(dc);
		if (otList.size() == 0)
			return new HashMap(0);
		Map resultMap = new HashMap();
		String emp = ((Overtimerequest) otList.get(0)).getOrEmpNo().getId();
		BigDecimal resultHours = ((Overtimerequest) otList.get(0))
				.getOrTiaoxiuHours();
		for (int i = 1; i < otList.size(); i++)
			if (emp.equals(((Overtimerequest) otList.get(i)).getOrEmpNo()
					.getId())) {
				resultHours.add(((Overtimerequest) otList.get(i))
						.getOrTiaoxiuHours());
			} else {
				resultMap.put(emp, resultHours);
				emp = ((Overtimerequest) otList.get(i)).getOrEmpNo().getId();
				resultHours.equals(((Overtimerequest) otList.get(i))
						.getOrTiaoxiuHours());
			}

		resultMap.put(emp, resultHours);
		return resultMap;
	}

	public List exeDeleteLeaveBalance(String empIds[], Integer leaveType[],
			String year) {
		if (empIds == null || empIds.length == 0) {
			return new ArrayList(0);
		} else {
			StringBuffer buffer = new StringBuffer(
					"delete from Leavebalance where lbEmpNo.id in ");
			buffer.append(buildInCondition(empIds));
			buffer.append(" and lbLeaveType in ");
			buffer.append(buildInCondition(leaveType));
			buffer.append((new StringBuilder()).append(" and lbYear = '")
					.append(year).append("'").toString());
			lb_DAO.exeHql(buffer.toString());
			String lastYear = String
					.valueOf(Integer.valueOf(year).intValue() - 1);
			String lastYearHql = (new StringBuilder()).append(
					"update Leavebalance set lbStatus=2 where lbEmpNo.id in ")
					.append(buildInCondition(empIds)).append(
							" and lbLeaveType in ").append(
							buildInCondition(leaveType)).append(
							" and lbYear = '").append(lastYear).append("'")
					.toString();
			lb_DAO.exeHql(lastYearHql);
			return new ArrayList(0);
		}
	}

	public List exeDeleteLeaveBalance(String recordIds[]) {
		if (recordIds == null || recordIds.length == 0)
			return new ArrayList(0);
		String hql = (new StringBuilder())
				.append(
						"select lbEmpNo.id,lbYear,lbLeaveType from Leavebalance where lbId in")
				.append(buildInCondition(recordIds)).toString();
		List list = lb_DAO.exeHqlList(hql);
		int size = list.size();
		String year = null;
		Integer leaveType = null;
		String empIds[] = new String[size];
		for (int i = 0; i < size; i++) {
			empIds[i] = ((Object[]) (Object[]) list.get(i))[0].toString();
			year = ((Object[]) (Object[]) list.get(i))[1].toString();
			leaveType = (Integer) ((Object[]) (Object[]) list.get(i))[2];
		}

		List result = exeDeleteLeaveBalance(empIds,
				new Integer[] { leaveType }, year);
		return result;
	}

	private Map getLeaveTypeSpecial(Integer ltSpecialCat[]) {
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavetype.class);
		dc.add(Restrictions.in("ltSpecialCat", ltSpecialCat));
		List leaveTypes = lb_DAO.findByCriteria(dc);
		Map typeMap = new HashMap();
		Leavetype lt;
		for (Iterator i$ = leaveTypes.iterator(); i$.hasNext(); typeMap.put(lt
				.getLtSpecialCat(), lt))
			lt = (Leavetype) i$.next();

		return typeMap;
	}

	public List exeSubmitLeaveBalance(String empIds[], Integer leaveType[],
			String year) {
		if (empIds == null || empIds.length == 0) {
			return new ArrayList(0);
		} else {
			String thisYearHql = (new StringBuilder()).append(
					"update Leavebalance set lbStatus=2 where lbEmpNo.id in ")
					.append(buildInCondition(empIds)).append(
							" and lbLeaveType in ").append(
							buildInCondition(leaveType)).append(
							" and lbYear = '").append(year).append("'")
					.toString();
			lb_DAO.exeHql(thisYearHql);
			String lastYear = String
					.valueOf(Integer.valueOf(year).intValue() - 1);
			String lastYearHql = (new StringBuilder()).append(
					"update Leavebalance set lbStatus=9 where lbEmpNo.id in ")
					.append(buildInCondition(empIds)).append(
							" and lbLeaveType in ").append(
							buildInCondition(leaveType)).append(
							" and lbYear = '").append(lastYear).append("'")
					.toString();
			lb_DAO.exeHql(lastYearHql);
			return new ArrayList(0);
		}
	}

	public List exeSubmitLeaveBalance(String recordIds[]) {
		if (recordIds == null || recordIds.length == 0)
			return new ArrayList(0);
		String hql = (new StringBuilder())
				.append(
						"select lbEmpNo.id,lbYear,lbLeaveType from Leavebalance where lbId in")
				.append(buildInCondition(recordIds)).toString();
		List list = lb_DAO.exeHqlList(hql);
		int size = list.size();
		String year = null;
		Integer leaveType = null;
		String empIds[] = new String[size];
		for (int i = 0; i < size; i++) {
			empIds[i] = ((Object[]) (Object[]) list.get(i))[0].toString();
			year = ((Object[]) (Object[]) list.get(i))[1].toString();
			leaveType = (Integer) ((Object[]) (Object[]) list.get(i))[2];
		}

		List result = exeSubmitLeaveBalance(empIds,
				new Integer[] { leaveType }, year);
		return result;
	}

	private String buildInCondition(Integer ids[]) {
		StringBuffer buffer = new StringBuffer(2 * ids.length + 2);
		buffer.append("(");
		int size = ids.length;
		for (int i = 0; i < size; i++) {
			buffer.append(ids[i]);
			if (i != size - 1)
				buffer.append(",");
		}

		buffer.append(")");
		return buffer.toString();
	}

	private String buildInCondition(String empIds[]) {
		StringBuffer buffer = new StringBuffer(39 * empIds.length + 2);
		buffer.append("(");
		int size = empIds.length;
		for (int i = 0; i < size; i++) {
			buffer.append("'").append(empIds[i]).append("'");
			if (i != size - 1)
				buffer.append(",");
		}

		buffer.append(")");
		return buffer.toString();
	}

	public List getAllYears() {
		Calendar date = Calendar.getInstance();
		Integer nextyear = Integer.valueOf(date.get(1) + 1);
		Integer currentyear = Integer.valueOf(date.get(1));
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		List year = lb_DAO
				.findByCriteria(detachedCriteria.setProjection(Projections
						.distinct(Projections.min("lbYear"))));
		List years = new LinkedList();
		String temp = (String) year.get(0);
		if (temp == null || "".equals(temp))
			temp = (new StringBuilder()).append(currentyear).append("")
					.toString();
		Integer init = Integer.valueOf(MyTools.parseNumber(temp, Integer.class)
				.intValue());
		year.clear();
		for (Integer i = init; i.intValue() <= nextyear.intValue();) {
			years.add(i);
			Integer integer = i;
			Integer integer1 = i = Integer.valueOf(i.intValue() + 1);
			Integer _tmp = integer;
		}

		return years;
	}

	public ILeavebalanceDAO getLb_DAO() {
		return lb_DAO;
	}

	public void setLb_DAO(ILeavebalanceDAO lb_DAO) {
		this.lb_DAO = lb_DAO;
	}

	public IEmployeeDAO getE_DAO() {
		return e_DAO;
	}

	public void setE_DAO(IEmployeeDAO e_dao) {
		e_DAO = e_dao;
	}

	public IDepartmentBO getDp_BO() {
		return dp_BO;
	}

	public void setDp_BO(IDepartmentBO dp_BO) {
		this.dp_BO = dp_BO;
	}

	public ILeaverequestBO getLr_BO() {
		return lr_BO;
	}

	public void setLr_BO(ILeaverequestBO lr_BO) {
		this.lr_BO = lr_BO;
	}

	public List getLeavebalanceForwardOfYear(int yearCurr) {
		List result = null;
		int year = yearCurr - 1;
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		dc.setFetchMode(Leavebalance.PROP_LB_EMP_NO, FetchMode.JOIN);
		dc.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, (new StringBuilder())
				.append("").append(year).toString()));
		result = lb_DAO.findByCriteria(dc);
		return result;
	}

	public List getOtForwardOfYear(int yearCurr) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		List result = null;
		int year = yearCurr - 1;
		java.util.Date start = null;
		java.util.Date end = null;
		Calendar cal = Calendar.getInstance();
		cal.set(1, year);
		cal.set(2, 0);
		cal.set(5, 1);
		try {
			start = format.parse(format.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		cal.add(1, 1);
		try {
			end = format.parse(format.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Integer status[] = { Integer.valueOf(15), Integer.valueOf(16) };
		DetachedCriteria dc = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Overtimerequest.class);
		dc.setFetchMode(Overtimerequest.PROP_OR_EMP_NO, FetchMode.JOIN);
		dc.add(Restrictions.in(Overtimerequest.PROP_OR_STATUS, status));
		dc.add(Restrictions.isNotNull("orTiaoxiuHours"));
		dc.add(Restrictions.ge("orTiaoxiuHours", new BigDecimal(0)));
		dc.add(Restrictions.ge("orStartDate", start));
		dc.add(Restrictions.le("orStartDate", end));
		result = lb_DAO.findByCriteria(dc);
		return result;
	}

	public List getLrForwardOfYear(int yearCurr) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		List result = null;
		int year = yearCurr - 1;
		java.util.Date start = null;
		java.util.Date end = null;
		Calendar cal = Calendar.getInstance();
		cal.set(1, year);
		cal.set(2, 0);
		cal.set(5, 1);
		try {
			start = format.parse(format.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		cal.add(1, 1);
		try {
			end = format.parse(format.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Leavetype tiaoxiuType = null;
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavetype.class);
		detachedCriteria.add(Restrictions.like(Leavetype.PROP_LT_NAME,
				"\u8C03\u4F11"));
		List ltList = lb_DAO.findByCriteria(detachedCriteria);
		tiaoxiuType = ltList == null ? null : (Leavetype) ltList.get(0);
		Integer status[] = { Integer.valueOf(15), Integer.valueOf(16) };
		DetachedCriteria detachedCriteria1 = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCriteria1.setFetchMode(Leaverequest.PROP_LR_EMP_NO,
				FetchMode.JOIN);
		detachedCriteria1.add(Restrictions.in(Leaverequest.PROP_LR_STATUS,
				status));
		detachedCriteria1.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO,
				tiaoxiuType));
		detachedCriteria1.add(Restrictions.ge("lrStartDate", start));
		detachedCriteria1.add(Restrictions.le("lrStartDate", end));
		result = lb_DAO.findByCriteria(detachedCriteria1);
		return result;
	}

	public BigDecimal getCurrEmpTiaoxiuRemind(String empId, List lbList) {
		BigDecimal tiaoxiuRemind = new BigDecimal(0);
		Iterator i$ = lbList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Leavebalance lb = (Leavebalance) i$.next();
			if (lb == null || empId == null
					|| !empId.equals(lb.getLbEmpNo().getId()))
				continue;
			tiaoxiuRemind = lb.getLbTiaoxiuForward();
			break;
		} while (true);
		if (tiaoxiuRemind == null)
			tiaoxiuRemind = new BigDecimal(0);
		return tiaoxiuRemind;
	}

	public BigDecimal getCurrEmpTiaoxiuOt(String empId, List orList) {
		BigDecimal tiaoxiuOt = new BigDecimal(0);
		Iterator i$ = orList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Overtimerequest or = (Overtimerequest) i$.next();
			if (or != null && empId != null
					&& empId.equals(or.getOrEmpNo().getId()))
				tiaoxiuOt = tiaoxiuOt.add(or.getOrTiaoxiuHours());
		} while (true);
		return tiaoxiuOt;
	}

	public BigDecimal getCurrEmpTiaoxiuLR(String empId, List lrList) {
		BigDecimal tiaoxiuLr = new BigDecimal(0);
		Iterator i$ = lrList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Leaverequest lr = (Leaverequest) i$.next();
			if (lr != null && empId != null
					&& empId.equals(lr.getLrEmpNo().getId()))
				tiaoxiuLr = tiaoxiuLr.add(lr.getLrTotalHours());
		} while (true);
		return tiaoxiuLr;
	}

	public List doSummaryEmpLeaveRequest(String empId, String leaveTypeId,
			String year) {
		if (StringUtils.isEmpty(year))
			return new ArrayList(0);
		List emps = getEmps(empId);
		if (emps.isEmpty())
			return new ArrayList(0);
		List leaveTypes = getLeavetTypes(leaveTypeId);
		if (leaveTypes.isEmpty())
			return new ArrayList(0);
		Map resultMap = getReportBeanMap(emps, leaveTypes);
		List lrList = getLeaveRequest(emps, leaveTypes, year);
		Map lrMap = injectLeaveRequestData(lrList, resultMap);
		Map specialMap = new HashMap();
		Set catIds = new HashSet();
		Leavetype lt;
		for (Iterator i$ = leaveTypes.iterator(); i$.hasNext(); catIds.add(lt
				.getLtSpecialCat())) {
			lt = (Leavetype) i$.next();
			specialMap.put(lt.getLtSpecialCat(), lt);
		}

		Map tiaoxiuMap = new HashMap();
		if (catIds.contains(Integer.valueOf(10))) {
			String empIds[] = getEmpIds(emps);
			tiaoxiuMap = getOTTiaoXiuMap(empIds, Integer.valueOf(year)
					.intValue());
		}
		List balanceList = getLeaveBalance(emps, catIds, year);
		injectLeavebalanceData(specialMap, balanceList, resultMap, lrMap,
				tiaoxiuMap);
		List result = new ArrayList();
		result.addAll(resultMap.values());
		return result;
	}

	private String[] getEmpIds(List empList) {
		String result[] = new String[empList.size()];
		for (int i = 0; i < empList.size(); i++)
			result[i] = ((Employee) empList.get(i)).getId();

		return result;
	}

	private void injectLeavebalanceData(Map specialMap, List balanceList,
			Map resultMap, Map lrMap, Map tiaoxiuMap) {
		Double hourPerday = Double.valueOf(ExaminDateUtil
				.getDefaultHoursPerDay());
		BigDecimal hourPerdayDecimal = new BigDecimal(hourPerday.doubleValue());
		Iterator i$ = balanceList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Leavebalance balance = (Leavebalance) i$.next();
			int spType = balance.getLbLeaveType().intValue();
			if (spType != 20) {
				String key = (new StringBuilder()).append(
						balance.getLbEmpNo().getId()).append("_").append(
						((Leavetype) specialMap.get(balance.getLbLeaveType()))
								.getLtNo()).toString();
				LeaveReportBean bean = (LeaveReportBean) resultMap.get(key);
				if (spType == 1) {
					BigDecimal wasted[] = getWasted((List) lrMap.get(key),
							balance, hourPerday.doubleValue());
					bean.setUsableDays(formatBigDecimal(
							balance.getLbDaysOfYear()).add(
							formatBigDecimal(balance.getLbBalForwardDay())));
					bean.setUsableHours(formatBigDecimal(
							balance.getLbHoursOfYear()).add(
							formatBigDecimal(balance.getLbBalForwardHour())));
					bean.setYearEndUsableDays(bean.getUsableDays().subtract(
							bean.getUsedDays()).subtract(
							bean.getApprovingDays()).subtract(wasted[1]));
					bean.setYearEndUsableHours(bean.getUsableHours().subtract(
							bean.getUsedHours()).subtract(
							bean.getApprovingHours()).subtract(wasted[0]));
				} else if (spType == 10) {
					BigDecimal wasted[] = getWasted((List) lrMap.get(key),
							balance, hourPerday.doubleValue());
					BigDecimal release = (BigDecimal) tiaoxiuMap.get(balance
							.getLbEmpNo().getId());
					bean.setUsableDays(formatBigDecimal(
							release.divide(hourPerdayDecimal)).add(
							formatBigDecimal(balance.getLbBalForwardDay())));
					bean.setUsableHours(formatBigDecimal(release).add(
							formatBigDecimal(balance.getLbBalForwardHour())));
					bean.setYearEndUsableDays(bean.getUsableDays().subtract(
							bean.getUsedDays()).subtract(
							bean.getApprovingDays()).subtract(wasted[1]));
					bean.setYearEndUsableHours(bean.getUsableHours().subtract(
							bean.getUsedHours()).subtract(
							bean.getApprovingHours()).subtract(wasted[0]));
				}
			}
		} while (true);
	}

	private BigDecimal[] getWasted(List lrList, Leavebalance leavebalance,
			double hourPerDay) {
		if (lrList == null)
			return (new BigDecimal[] { new BigDecimal(0), new BigDecimal(0) });
		LrDataCheckImpl check = (LrDataCheckImpl) SpringBeanFactory
				.getBean("lrDataCheck");
		Double balFwdHours = check.getBalFwdHours(leavebalance, hourPerDay);
		Double wastedHours;
		if (leavebalance.getLbBalEndDate() == null) {
			wastedHours = new Double(0.0D);
		} else {
			double allHoursArr[] = check.getLeaveHoursBeforAfter(lrList,
					leavebalance.getLbBalEndDate());
			wastedHours = Double.valueOf(allHoursArr[0] >= balFwdHours
					.doubleValue() ? (new Double(0.0D)).doubleValue()
					: balFwdHours.doubleValue() - allHoursArr[0]);
		}
		BigDecimal rs[] = new BigDecimal[2];
		rs[0] = new BigDecimal(wastedHours.doubleValue());
		rs[1] = new BigDecimal(wastedHours.doubleValue() / hourPerDay);
		return rs;
	}

	private Map injectLeaveRequestData(List lrList, Map resultMap) {
		Map lrMap = new HashMap();
		Iterator i$ = lrList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Leaverequest lr = (Leaverequest) i$.next();
			String key = (new StringBuilder()).append(lr.getLrEmpNo().getId())
					.append("_").append(lr.getLrLtNo().getLtNo()).toString();
			List empLrList = (List) lrMap.get(key);
			if (empLrList == null)
				empLrList = new ArrayList();
			empLrList.add(lr);
			lrMap.put(key, empLrList);
			LeaveReportBean bean = (LeaveReportBean) resultMap.get(key);
			if (lr.getLrStatus().intValue() == 15
					|| lr.getLrStatus().intValue() == 16) {
				bean.setUsedDays(bean.getUsedDays().add(
						formatBigDecimal(lr.getLrTotalDays())));
				bean.setUsedHours(bean.getUsedHours().add(
						formatBigDecimal(lr.getLrTotalHours())));
			} else if (lr.getLrStatus().intValue() != 21
					&& lr.getLrStatus().intValue() != 22) {
				bean.setApprovingDays(bean.getApprovingDays().add(
						formatBigDecimal(lr.getLrTotalDays())));
				bean.setApprovingHours(bean.getApprovingHours().add(
						formatBigDecimal(lr.getLrTotalHours())));
			}
		} while (true);
		return lrMap;
	}

	private Map<String, LeaveReportBean> getReportBeanMap(List emps,
			List<Leavetype> leaveTypes) {
		Map specialCatMap = getLeaveTypeMap();
		Map resultMap = new HashMap();
		for (Iterator i$ = emps.iterator(); i$.hasNext();) {
			Employee emp = (Employee) i$.next();
			for (Leavetype lt : leaveTypes) {
				String key = emp.getId() + "_" + lt.getLtNo();
				LeaveReportBean bean = new LeaveReportBean();
				bean.setLeaveTypeCategory(lt.getLtSpecialCat());
				bean.setLeaveTypeCategoryName((String) specialCatMap.get(bean
						.getLeaveTypeCategory()));
				bean.setLeaveTypeId(lt.getLtNo());
				bean.setLeaveTypeName(lt.getLtName());
				bean.setEmpId(emp.getId());
				bean.setEmpName(emp.getEmpName());
				resultMap.put(key, bean);
			}
		}
		Employee emp;
		return resultMap;
	}

	private List getEmps(String empid) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Employee.class);
		detachedCriteria.add(Restrictions.eq(Employee.PROP_EMP_STATUS, Integer
				.valueOf(1)));
		if (StringUtils.isNotEmpty(empid))
			detachedCriteria.add(Restrictions.eq(Employee.PROP_ID, empid));
		return e_DAO.findByCriteria(detachedCriteria);
	}

	private List getLeavetTypes(String leaveTypeId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavetype.class);
		if (StringUtils.isNotEmpty(leaveTypeId))
			detachedCriteria.add(Restrictions.eq(Leavetype.PROP_LT_NO,
					leaveTypeId));
		return e_DAO.findByCriteria(detachedCriteria);
	}

	private BigDecimal formatBigDecimal(BigDecimal bigDecimal) {
		return BigDecimalUtils.convertToZeroIfNull(bigDecimal);
	}

	private Map getLeaveTypeMap() {
		Map result = new HashMap();
		result.put(Integer.valueOf(0), "\u4E8B\u5047");
		result.put(Integer.valueOf(1), "\u5E74\u5047");
		result.put(Integer.valueOf(3), "\u75C5\u5047");
		result.put(Integer.valueOf(4), "\u75C5\u5047\u4F4F\u9662");
		result.put(Integer.valueOf(5), "\u5E26\u85AA\u75C5\u5047");
		result.put(Integer.valueOf(6), "\u5A5A\u5047");
		result.put(Integer.valueOf(7), "\u4EA7\u5047");
		result.put(Integer.valueOf(8), "\u51FA\u5DEE");
		result.put(Integer.valueOf(9), "\u56E0\u516C\u5916\u51FA");
		result.put(Integer.valueOf(10), "\u8C03\u4F11(\u4E0D\u8FC7\u671F)");
		result.put(Integer.valueOf(11), "\u8C03\u4F11(\u8FC7\u671F)");
		result.put(Integer.valueOf(20), "\u5176\u4ED6");
		return result;
	}

	private List getLeaveBalance(List empId, Set leaveTypeIds, String year) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.setFetchMode(Leavebalance.PROP_LB_EMP_NO,
				FetchMode.JOIN);
		detachedCriteria.add(Restrictions
				.in(Leavebalance.PROP_LB_EMP_NO, empId));
		if (!leaveTypeIds.isEmpty())
			detachedCriteria.add(Restrictions.in(
					Leavebalance.PROP_LB_LEAVE_TYPE, leaveTypeIds));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, year));
		List result = lb_DAO.findByCriteria(detachedCriteria);
		return result;
	}

	private List getLeaveRequest(List empId, List leaveTypeId, String year) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCriteria.setFetchMode(Leaverequest.PROP_LR_LT_NO,
				FetchMode.JOIN);
		detachedCriteria.setFetchMode(Leaverequest.PROP_LR_EMP_NO,
				FetchMode.JOIN);
		int intYear = Integer.valueOf(year).intValue();
		java.util.Date startDate = DateUtil.getYearFirstDay(intYear);
		java.util.Date endDate = DateUtil.getYearFirstDay(intYear + 1);
		detachedCriteria.add(Restrictions.ge(Leaverequest.PROP_LR_START_DATE,
				startDate));
		detachedCriteria.add(Restrictions.lt(Leaverequest.PROP_LR_END_DATE,
				endDate));
		detachedCriteria.add(Restrictions
				.in(Leaverequest.PROP_LR_EMP_NO, empId));
		detachedCriteria.add(Restrictions.in(Leaverequest.PROP_LR_LT_NO,
				leaveTypeId));
		List lrList = lb_DAO.findByCriteria(detachedCriteria);
		return lrList;
	}

	public Leavebalance getLeaveBalanceById(String id) {
		return (Leavebalance) lb_DAO.loadObject(
				com.wyzz.hr.pojo.Leavebalance.class, id, null, new boolean[0]);
	}

	public void updateLeaveBalance(Leavebalance leavebalance) {
		lb_DAO.updateObject(leavebalance);
	}

	public void saveOrUpdateLeaveBalance(List lbList) {
		lb_DAO.saveOrupdate(lbList);
	}

	public void deleteLeaveBalance(String id) {
		lb_DAO.deleteObject(com.wyzz.hr.pojo.Leavebalance.class, id);
	}

	public List getEmpLBOfYear(List empList, Integer leaveType, String year) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.add(Restrictions.in(Leavebalance.PROP_LB_EMP_NO,
				empList));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_LEAVE_TYPE,
				leaveType));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, year));
		List result = lb_DAO.findByCriteria(detachedCriteria);
		return result;
	}

	public List getLeaveBalance(List empNos, List leaveTypes, String year) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leavebalance.class);
		detachedCriteria.createAlias(Leavebalance.PROP_LB_EMP_NO,
				Leavebalance.PROP_LB_EMP_NO, 1);
		detachedCriteria.add(Restrictions.in((new StringBuilder()).append(
				Leavebalance.PROP_LB_EMP_NO).append(".").append(
				Employee.PROP_EMP_DISTINCT_NO).toString(), empNos));
		detachedCriteria.add(Restrictions.in(Leavebalance.PROP_LB_LEAVE_TYPE,
				leaveTypes));
		detachedCriteria.add(Restrictions.eq(Leavebalance.PROP_LB_YEAR, year));
		List result = lb_DAO.findByCriteria(detachedCriteria);
		if (result.isEmpty())
			return null;
		else
			return result;
	}

	private ILeavebalanceDAO lb_DAO;
	private IEmployeeDAO e_DAO;
	private IDepartmentBO dp_BO;
	private ILeaverequestBO lr_BO;
}
